/*
Copyright (C) 2011 Ing. Marek Hubal

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

#include <Windows.h>
#include "cbi_core.h"
#include <stdio.h>

#include "cbi_core2.h"

#pragma warning (disable: 4996)

//#define _CRTDBG_MAP_ALLOC
//#include <stdlib.h>
//#include <crtdbg.h>

#pragma pack(1)
typedef struct {
	int STRUCTURE_SIZE;
	int COMPRESSION_METHOD;
	int PAGE_INDEX;
	unsigned char* RESULT_DATA;
	unsigned int RESULT_DATA_SIZE;
	double ELAPSED_TIME;
	int ERROR_CODE;
} CONVERT_PARAMS, *PCONVERT_PARAMS;
#pragma pack()

// ....................................................................................................................
// Entry point kniznice
// ....................................................................................................................
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
	return TRUE;
}
// ....................................................................................................................

// ....................................................................................................................
// Exportovana funkcia 
// ....................................................................................................................
extern "C" __declspec(dllexport) int cbi_get_stream_info(const char* pFileName, PCBI_STREAM_INFO Result) {
	INT32 R = ICBIStream::ReadStreamInfo(pFileName, Result); // Volam ziskanie info
	return R;
}
// ....................................................................................................................

// ....................................................................................................................
// Exportovana funkcia 
// ....................................................................................................................
extern "C" __declspec(dllexport) int cbi_get_pages_info(const char* pFileName, PCBI_PAGE_INFO PagesResult) {
	INT32 R = ICBIStream::ReadPagesInfo(pFileName, PagesResult); // Volam ziskanie info
	return R;
}
// ....................................................................................................................

// ....................................................................................................................
// Exportovana funkcia
// ....................................................................................................................
extern "C" __declspec(dllexport) void cbi_free_data(void* pData) {
	if (pData != NULL) delete (PBYTE)pData;
}
// ....................................................................................................................

#include "cbi_core2.h"

// ....................................................................................................................
// Exportovana funkcia
// ....................................................................................................................
extern "C" __declspec(dllexport) void* cbi_create_stream(const char* pFileName, const void* pConvertParams) {
	PCONVERT_PARAMS Params = (PCONVERT_PARAMS)pConvertParams;
	Params->ELAPSED_TIME = 0; // Inicializacia

	IStopWatch W;
	W.StartMeassure();

	ICBIStream *Stream = ICBIStream::CreateCBIStream(Params->COMPRESSION_METHOD);
	INT32 R = Stream->Create(pFileName);
	if (R != 0) {
		delete Stream;
		Stream = NULL;
		Params->ERROR_CODE = R;
	}

	W.EndMeassure(1);
	Params->ELAPSED_TIME = W.ElapsedTime();
	return Stream;
}
// ....................................................................................................................

// ....................................................................................................................
// Exportovana funkcia
// ....................................................................................................................
extern "C" __declspec(dllexport) int cbi_close_stream(void *pStream, const void* pConvertParams) {
	PCONVERT_PARAMS Params = (PCONVERT_PARAMS)pConvertParams;
	Params->ELAPSED_TIME = 0; // Inicializacia

	IStopWatch W;
	W.StartMeassure();

	if (pStream == NULL) return 0; // Neplatny stream?

	INT32 R = ((ICBIStream*)pStream)->Close(); // Uzatvorim stream
	delete (ICBIStream*)pStream;

	W.EndMeassure(1);
	Params->ELAPSED_TIME = W.ElapsedTime();
	return R; // Vratim vysledok uzatvorenia
}
// ....................................................................................................................

// ....................................................................................................................
// Exportovana funkcia
// ....................................................................................................................
extern "C" __declspec(dllexport) int cbi_add_bmp_page_to_stream(void* pStream, const char* pFileName, const void* pConvertParams) {
	PCONVERT_PARAMS Params = (PCONVERT_PARAMS)pConvertParams;
	Params->ELAPSED_TIME = 0; // Inicializacia

	IStopWatch W;
	W.StartMeassure();

	IBitmap2 *Bmp = new IBitmap2(); // Vytvorim objekt
	INT32 R = Bmp->LoadFromBMP(pFileName);
	if (R != 0) {
		delete Bmp; // Zrusim image
		return R;
	}

	R = ((ICBIStream*)pStream)->AddPage(Bmp); // Vytvorim CBI stream
	if (R != 0) {
		delete Bmp; // Zrusim image
		return R - 100;
	}

	delete Bmp; // Zrusim image

	W.EndMeassure(1);
	Params->ELAPSED_TIME = W.ElapsedTime();

	return 0;
}
// ....................................................................................................................

// ....................................................................................................................
// Exportovana funkcia
// ....................................................................................................................
extern "C" __declspec(dllexport) void* cbi_open_stream(const char* pFileName, const void* pConvertParams) {
	PCONVERT_PARAMS Params = (PCONVERT_PARAMS)pConvertParams;
	Params->ELAPSED_TIME = 0; // Inicializacia

	IStopWatch W;
	W.StartMeassure();

	ICBIStream *Stream = ICBIStream::OpenCBIStream(pFileName, Params->ERROR_CODE);

	W.EndMeassure(1);
	Params->ELAPSED_TIME = W.ElapsedTime();
	return Stream;
}
// ....................................................................................................................

// ....................................................................................................................
// Exportovana funkcia
// ....................................................................................................................
extern "C" __declspec(dllexport) int cbi_extract_bmp_page(void* pStream, const char* pFileName, int pPageIndex, const void* pConvertParams) {
	PCONVERT_PARAMS Params = (PCONVERT_PARAMS)pConvertParams;
	Params->ELAPSED_TIME = 0; // Inicializacia

	IStopWatch W;
	W.StartMeassure();

	IBitmap2 *Bmp = new IBitmap2(); // Vytvorim objekt
	INT32 R = ((ICBIStream*)pStream)->GetPageImage(pPageIndex, Bmp);
	if (R != 0) {
		delete Bmp; // Zrusim image
		return R;
	}

	R = Bmp->SaveToBMP(pFileName);
	delete Bmp; // Zrusim image

	W.EndMeassure(1);
	Params->ELAPSED_TIME = W.ElapsedTime();

	return R;
}
// ....................................................................................................................
